home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / hplip / copier / copier.py < prev   
Text File  |  2008-10-13  |  14KB  |  381 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. from __future__ import generators
  23.  
  24. # Std Lib
  25. import sys
  26. import os
  27. import os.path
  28. import time
  29. import threading
  30. import Queue
  31. from cStringIO import StringIO
  32.  
  33. # Local
  34. from base.g import *
  35. from base.codes import *
  36. from base import device, utils, status, pml
  37.  
  38. # Event queue values (UI ==> Copy thread)
  39. COPY_CANCELED = 1
  40.  
  41. # Update queue values (Copy thread ==> UI)
  42. STATUS_IDLE = 0
  43. STATUS_SETTING_UP = 1
  44. STATUS_WARMING_UP = 2
  45. STATUS_ACTIVE = 3
  46. STATUS_DONE = 4
  47. STATUS_ERROR = 5
  48.  
  49.  
  50. # PML Copier Only
  51. class PMLCopyDevice(device.Device):
  52.     def __init__(self, device_uri=None, printer_name=None, 
  53.                  service=None, callback=None):
  54.  
  55.         device.Device.__init__(self, device_uri, printer_name,
  56.                                service, callback)
  57.  
  58.         self.copy_thread = None
  59.  
  60.     def copy(self, num_copies=1, contrast=0, reduction=100,
  61.              quality=pml.COPIER_QUALITY_NORMAL, 
  62.              fit_to_page=pml.COPIER_FIT_TO_PAGE_ENABLED,
  63.              scan_style=SCAN_STYLE_FLATBED,
  64.              update_queue=None, event_queue=None): 
  65.  
  66.         if not self.isCopyActive():
  67.             self.copy_thread = PMLCopyThread(self, num_copies, contrast, reduction, quality, 
  68.                                              fit_to_page, scan_style, update_queue, event_queue)
  69.             self.copy_thread.start()
  70.             return True
  71.         else:
  72.             return False
  73.  
  74.     def isCopyActive(self):
  75.         if self.copy_thread is not None:
  76.             return self.copy_thread.isAlive()
  77.         else:
  78.             return False
  79.  
  80.     def waitForCopyThread(self):
  81.         if self.copy_thread is not None and \
  82.             self.copy_thread.isAlive():
  83.  
  84.             self.copy_thread.join()
  85.  
  86.  
  87.  
  88. class PMLCopyThread(threading.Thread):
  89.     def __init__(self, dev, num_copies, contrast, reduction, quality, 
  90.                  fit_to_page, scan_style, 
  91.                  update_queue=None, event_queue=None):
  92.  
  93.         threading.Thread.__init__(self)
  94.         self.dev = dev
  95.         self.num_copies = num_copies
  96.         self.contrast = contrast
  97.         self.reduction = reduction
  98.         self.quality = quality
  99.         self.fit_to_page = fit_to_page
  100.         self.scan_style = scan_style
  101.         self.event_queue = event_queue
  102.         self.update_queue = update_queue
  103.         self.prev_update = ''
  104.         self.copy_type = self.dev.copy_type
  105.         log.debug("Copy-type = %d" % self.copy_type)
  106.  
  107.     def run(self):
  108.         STATE_DONE = 0
  109.         STATE_ERROR = 5
  110.         STATE_ABORTED = 10
  111.         STATE_SUCCESS = 20
  112.         STATE_BUSY = 25
  113.         STATE_SET_TOKEN = 30
  114.         STATE_SETUP_STATE = 40
  115.         STATE_SETUP_PARAMS = 50
  116.         STATE_START = 60
  117.         STATE_ACTIVE = 70
  118.         STATE_RESET_TOKEN = 80
  119.  
  120.         state = STATE_SET_TOKEN
  121.  
  122.         while state != STATE_DONE: # ------------------------- Copier Thread
  123.             # revisit - Checking cancel and setting state here means
  124.             # every state can unconditionally transition to STATE_ABORTED.
  125.             # This has not been verified.
  126.             # if self.check_for_cancel():
  127.                 # state = STATE_ABORTED
  128.  
  129.             if state == STATE_ABORTED:
  130.                 log.debug("%s State: Aborted" % ("*"*20))
  131.                 self.write_queue(STATUS_DONE) # This was STATUS_ERROR.
  132.                 state = STATE_RESET_TOKEN
  133.  
  134.             if state == STATE_ERROR:
  135.                 log.debug("%s State: Error" % ("*"*20))
  136.                 self.write_queue(STATUS_ERROR)
  137.                 state = STATE_RESET_TOKEN
  138.  
  139.             elif state == STATE_SUCCESS:
  140.                 log.debug("%s State: Success" % ("*"*20))
  141.                 self.write_queue(STATUS_DONE)
  142.                 state = STATE_RESET_TOKEN
  143.  
  144.             elif state == STATE_BUSY:
  145.                 log.debug("%s State: Busy" % ("*"*20))
  146.                 self.write_queue(STATUS_ERROR)
  147.                 state = STATE_RESET_TOKEN
  148.  
  149.             elif state == STATE_SET_TOKEN:
  150.                 log.debug("%s State: Acquire copy token" % ("*"*20))
  151.  
  152.                 self.write_queue(STATUS_SETTING_UP)
  153.  
  154.                 try:
  155.                     result_code, token = self.dev.getPML(pml.OID_COPIER_TOKEN)
  156.                 except Error:
  157.                     log.debug("Unable to acquire copy token (1).")
  158.                     state = STATE_SETUP_STATE
  159.                 else:
  160.                     if result_code > pml.ERROR_MAX_OK:
  161.                         state = STATE_SETUP_STATE
  162.                         log.debug("Skipping token acquisition.")
  163.                     else:
  164.                         token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
  165.                         log.debug("Setting token: %s" % token)
  166.                         try:
  167.                             self.dev.setPML(pml.OID_COPIER_TOKEN, token)
  168.                         except Error:
  169.                             log.error("Unable to acquire copy token (2).")
  170.                             state = STATUS_ERROR
  171.                         else:
  172.                             result_code, check_token = self.dev.getPML(pml.OID_COPIER_TOKEN)
  173.  
  174.                             if check_token == token:
  175.                                 state = STATE_SETUP_STATE
  176.                             else:
  177.                                 log.error("Unable to acquire copy token (3).")
  178.                                 state = STATE_ERROR
  179.  
  180.             elif state == STATE_SETUP_STATE:
  181.                 log.debug("%s State: Setup state" % ("*"*20))
  182.  
  183.                 if self.copy_type == COPY_TYPE_DEVICE:
  184.                     result_code, copy_state = self.dev.getPML(pml.OID_COPIER_JOB)
  185.  
  186.                     if copy_state == pml.COPIER_JOB_IDLE:
  187.                         self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_SETUP)
  188.                         state = STATE_SETUP_PARAMS
  189.  
  190.                     else:
  191.                         state = STATE_BUSY
  192.  
  193.                 elif self.copy_type == COPY_TYPE_AIO_DEVICE:
  194.                     result_code, copy_state = self.dev.getPML(pml.OID_SCAN_TO_PRINTER)
  195.  
  196.                     if copy_state == pml.SCAN_TO_PRINTER_IDLE:
  197.                         state = STATE_SETUP_PARAMS
  198.  
  199.                     else:
  200.                         state = STATE_BUSY
  201.  
  202.  
  203.  
  204.             elif state == STATE_SETUP_PARAMS:
  205.                 log.debug("%s State: Setup Params" % ("*"*20))
  206.  
  207.                 if self.num_copies < 0: self.num_copies = 1
  208.                 if self.num_copies > 99: self.num_copies = 99
  209.  
  210.                 if self.copy_type == COPY_TYPE_DEVICE: # MFP
  211.  
  212.                     # num_copies
  213.                     self.dev.setPML(pml.OID_COPIER_JOB_NUM_COPIES, self.num_copies)
  214.  
  215.                     # contrast
  216.                     self.dev.setPML(pml.OID_COPIER_JOB_CONTRAST, self.contrast)
  217.  
  218.                     # reduction
  219.                     self.dev.setPML(pml.OID_COPIER_JOB_REDUCTION, self.reduction)
  220.  
  221.                     # quality
  222.                     self.dev.setPML(pml.OID_COPIER_JOB_QUALITY, self.quality)
  223.  
  224.                     # fit_to_page
  225.                     if self.scan_style == SCAN_STYLE_FLATBED:
  226.                         self.dev.setPML(pml.OID_COPIER_JOB_FIT_TO_PAGE, self.fit_to_page)
  227.  
  228.                 else: # AiO
  229.                     # num_copies
  230.                     self.dev.setPML(pml.OID_COPIER_NUM_COPIES_AIO, self.num_copies)
  231.  
  232.                     # contrast
  233.                     self.contrast = (self.contrast * 10 / 25) + 50
  234.                     self.dev.setPML(pml.OID_COPIER_CONTRAST_AIO, self.contrast)
  235.  
  236.                     if self.fit_to_page == pml.COPIER_FIT_TO_PAGE_ENABLED:
  237.                         self.reduction = 0
  238.  
  239.                     # reduction
  240.                     self.dev.setPML(pml.OID_COPIER_REDUCTION_AIO, self.reduction)
  241.  
  242.                     # quality
  243.                     self.dev.setPML(pml.OID_COPIER_QUALITY_AIO, self.quality)
  244.  
  245.                     self.dev.setPML(pml.OID_PIXEL_DATA_TYPE, pml.PIXEL_DATA_TYPE_COLOR_24_BIT)
  246.                     self.dev.setPML(pml.OID_COPIER_SPECIAL_FEATURES, pml.COPY_FEATURE_NONE)
  247.                     self.dev.setPML(pml.OID_COPIER_PHOTO_MODE, pml.ENHANCE_LIGHT_COLORS | pml.ENHANCE_TEXT)
  248.                     
  249.                     # tray select
  250.                     self.dev.setPML(pml.OID_COPIER_JOB_INPUT_TRAY_SELECT, pml.COPIER_JOB_INPUT_TRAY_1)
  251.                     
  252.                     # media type
  253.                     self.dev.setPML(pml.OID_COPIER_MEDIA_TYPE, pml.COPIER_MEDIA_TYPE_AUTOMATIC)
  254.                     
  255.                     # pixel data type
  256.                     self.dev.setPML(pml.OID_PIXEL_DATA_TYPE, pml.PIXEL_DATA_TYPE_COLOR_24_BIT)
  257.                     
  258.                     # special features
  259.                     self.dev.setPML(pml.OID_COPIER_SPECIAL_FEATURES, pml.COPY_FEATURE_NONE)
  260.                     
  261.                     # media size
  262.                     self.dev.setPML(pml.OID_COPIER_JOB_MEDIA_SIZE, pml.COPIER_JOB_MEDIA_SIZE_US_LETTER)
  263.                     
  264.  
  265.                 
  266.                 
  267.                 log.debug("num_copies = %d" % self.num_copies)
  268.                 log.debug("contrast= %d" % self.contrast)
  269.                 log.debug("reduction = %d" % self.reduction)
  270.                 log.debug("quality = %d" % self.quality)
  271.                 log.debug("fit_to_page = %d" % self.fit_to_page)
  272.  
  273.                 state = STATE_START
  274.  
  275.             elif state == STATE_START:
  276.                 log.debug("%s State: Start" % ("*"*20))
  277.  
  278.                 if self.copy_type == COPY_TYPE_DEVICE:
  279.                     self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_START)
  280.  
  281.                 elif self.copy_type == COPY_TYPE_AIO_DEVICE:
  282.                     self.dev.setPML(pml.OID_SCAN_TO_PRINTER, pml.SCAN_TO_PRINTER_START)
  283.  
  284.                 state = STATE_ACTIVE
  285.  
  286.             elif state == STATE_ACTIVE:
  287.                 log.debug("%s State: Active" % ("*"*20))
  288.  
  289.                 if self.copy_type == COPY_TYPE_DEVICE:
  290.                     while True:
  291.                         result_code, copy_state = self.dev.getPML(pml.OID_COPIER_JOB)
  292.  
  293.                         if self.check_for_cancel():
  294.                             self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_IDLE) # cancel
  295.                             state = STATE_ABORTED
  296.                             break
  297.  
  298.                         if copy_state == pml.COPIER_JOB_START:
  299.                             log.debug("state = start")
  300.                             time.sleep(1)
  301.                             continue
  302.  
  303.                         if copy_state == pml.COPIER_JOB_ACTIVE:
  304.                             self.write_queue(STATUS_ACTIVE)
  305.                             log.debug("state = active")
  306.                             time.sleep(2)
  307.                             continue
  308.  
  309.                         elif copy_state == pml.COPIER_JOB_ABORTING:
  310.                             log.debug("state = aborting")
  311.                             state = STATE_ABORTED
  312.                             break
  313.  
  314.                         elif copy_state == pml.COPIER_JOB_IDLE:
  315.                             log.debug("state = idle")
  316.                             state = STATE_SUCCESS
  317.                             break
  318.  
  319.                 elif self.copy_type == COPY_TYPE_AIO_DEVICE:
  320.                     while True:
  321.                         result_code, copy_state = self.dev.getPML(pml.OID_SCAN_TO_PRINTER)
  322.  
  323.                         if self.check_for_cancel():
  324.                             self.dev.setPML(pml.OID_SCAN_TO_PRINTER, pml.SCAN_TO_PRINTER_IDLE) # cancel
  325.                             state = STATE_ABORTED
  326.                             break
  327.  
  328.                         if copy_state == pml.SCAN_TO_PRINTER_START:
  329.                             log.debug("state = start")
  330.                             time.sleep(1)
  331.                             continue
  332.  
  333.                         if copy_state == pml.SCAN_TO_PRINTER_ACTIVE:
  334.                             self.write_queue(STATUS_ACTIVE)
  335.                             log.debug("state = active")
  336.                             time.sleep(2)
  337.                             continue
  338.  
  339.                         elif copy_state == pml.SCAN_TO_PRINTER_ABORTED:
  340.                             log.debug("state = aborting")
  341.                             state = STATE_ABORTED
  342.                             break
  343.  
  344.                         elif copy_state == pml.SCAN_TO_PRINTER_IDLE:
  345.                             log.debug("state = idle")
  346.                             state = STATE_SUCCESS
  347.                             break
  348.  
  349.  
  350.             elif state == STATE_RESET_TOKEN:
  351.                 log.debug("%s State: Release copy token" % ("*"*20))
  352.  
  353.                 try:
  354.                     self.dev.setPML(pml.OID_COPIER_TOKEN, '\x00'*16)
  355.                 except Error:
  356.                     log.error("Unable to release copier token.")
  357.  
  358.                 self.dev.close() # Close the device.
  359.                 
  360.                 state = STATE_DONE
  361.  
  362.  
  363.     def check_for_cancel(self):
  364.         canceled = False
  365.         while self.event_queue.qsize():
  366.             try:
  367.                 event = self.event_queue.get(0)
  368.                 if event == COPY_CANCELED:
  369.                     canceled = True
  370.                     log.debug("Cancel pressed!")
  371.             except Queue.Empty:
  372.                 break
  373.  
  374.         return canceled
  375.  
  376.     def write_queue(self, message):
  377.         if self.update_queue is not None and message != self.prev_update:
  378.             self.update_queue.put(message)
  379.             time.sleep(0)
  380.             self.prev_update = message
  381.